import { Form, Input, Select, TimePicker, DatePicker, Radio } from "antd";
import { isEmpty, notExist, toArray } from "wsp-toolkit";
import { EyeInvisibleOutlined, EyeTwoTone } from "@ant-design/icons";
import { useState, useImperativeHandle, forwardRef, useMemo } from "react";
import { InputType } from "../../enum.js";
import dayjs from "dayjs";
import style from "./index.module.css";

const getMsgPrefix = (iptType) => {
  return (
    {
      [InputType.select]: "请选择",
    }[iptType] || "请输入"
  );
};

/**
 * @param props {{
 *   children?: JSX.Element;
 *   formItems: FormItem[];
 *   colon?: boolean;
 *   form?: any;
 *   className?: string;
 *   columnRepeat?: number;
 * }}
 */
const SForm = (props, wrapRef) => {
  const CusForm = forwardRef((props, ref) => {
    const {
      formItems = [],
      children,
      colon = false,
      form,
      className = "",
      columnRepeat = 3,
      initialValues,
      onValuesChange,
      onFieldsChange,
      ...otherProps
    } = props;
    const _form = form || Form.useForm()[0];
    const validate = async () => {
      return _form
        .validateFields()
        .then((data) => [true, data])
        .catch(() => [false, null]);
    };
    useImperativeHandle(
      ref,
      () => {
        return {
          validate: validate,
          ..._form,
        };
      },
      [_form],
    );
    const items = formItems.reduce((res, item) => {
      if (isEmpty(item)) return res;
      const rules = toArray(item.rules);
      const isValidate = item.isValidate ?? true;
      if (isValidate && item.required && !rules.some((rule) => rule.required)) {
        rules.push({
          required: true,
          message: `${getMsgPrefix(item.inputType)}${item.label}`,
        });
      }
      res.push({
        ...item,
        rules,
      });
      return res;
    }, []);

    const [timeValue, setTimeValue] = useState(null);
    const timePickerChange = (time) => setTimeValue(time);

    const [timeRangeValue, setTimeRange] = useState(null);
    const timeRangeChange = (val) => setTimeRange(val);
    return (
      <Form
        ref={ref}
        scrollToFirstError={true}
        form={_form}
        autoComplete={"off"}
        colon={colon}
        style={{
          display: "grid",
          gridTemplateColumns: `repeat(${columnRepeat}, 1fr)`,
          gap: "16px 16px",
        }}
        className={`${style.form} ${className}`}
        initialValues={initialValues}
        onValuesChange={onValuesChange}
        onFieldsChange={onFieldsChange}
        {...otherProps}
      >
        {items.map((item, idx) => {
          const {
            name,
            label,
            span,
            inputType,
            bindProps,
            render,
            isValidate,
            style,
            ...otherCfg
          } = item;
          const options = toArray(item.options);
          const ItemComponent = render;
          return (
            <Form.Item
              key={idx}
              name={name}
              label={label}
              style={{ gridColumnStart: span && `span ${span}`, ...style }}
              {...otherCfg}
            >
              {(inputType === InputType.input || notExist(inputType)) && (
                <Input {...bindProps} />
              )}
              {inputType === InputType.textArea && (
                <Input.TextArea
                  autoSize={{ minRows: 4, maxRows: 8 }}
                  {...bindProps}
                />
              )}
              {inputType === InputType.select && (
                <Select {...bindProps} options={options} />
              )}
              {inputType === InputType.password && (
                <Input.Password
                  {...bindProps}
                  iconRender={(visible) =>
                    visible ? <EyeTwoTone /> : <EyeInvisibleOutlined />
                  }
                />
              )}
              {inputType === InputType.timePicker && (
                <TimePicker
                  style={{ width: "100%" }}
                  format={"hh:mm:ss"}
                  {...bindProps}
                />
              )}
              {inputType === InputType.timeRange && (
                <TimePicker.RangePicker
                  style={{ width: "100%" }}
                  format={"hh:mm:ss"}
                  {...bindProps}
                />
              )}
              {inputType == InputType.datePicker && (
                <DatePicker
                  style={{ width: "100%" }}
                  format={"YYYY-MM-DD"}
                  {...bindProps}
                />
              )}
              {inputType == InputType.dateRange && (
                <DatePicker.RangePicker
                  style={{ width: "100%" }}
                  format={"YYYY-MM-DD"}
                  {...bindProps}
                />
              )}
              {inputType == InputType.radioGroup && <Radio.Group size="middle" options={options} {...bindProps}></Radio.Group>}

              {inputType == "render" && (
                <ItemComponent {...bindProps} />
              )}


            </Form.Item>
          );
        })}
        {children && <Form.Item>{children}</Form.Item>}
      </Form>
    );
  });
  return <CusForm {...props} ref={wrapRef} />;
};
const FRForm = forwardRef(SForm);
FRForm.useForm = Form.useForm;
FRForm.useWatch = Form.useWatch;
FRForm.useFormInstance = Form.useFormInstance;

export default FRForm;
